package com.basker.pisces.orm.data;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.basker.pisces.orm.data.meta.FieldMeta;
import com.basker.pisces.orm.data.meta.TableMeta;

/**
 * 数据表，内部数据由多个数据行组成
 *
 * @author hangwen
 */
public class DataTable {
    private List<DataRow> rows;
    private TableMeta tableMeta;
    private Map<Object, Integer> rowIndexMap;

    public DataTable(TableMeta tableMeta) {
        this.tableMeta = tableMeta;
    }

    /**
     * 添加resultSet，组装rows
     *
     * @param resultSet
     * @throws SQLException
     */
    public void addResultSet(ResultSet resultSet) throws SQLException {
        List<FieldMeta> fieldMetas = this.tableMeta.getSelectFieldMetas();

        while (resultSet.next()) {
            DataRow row = this.createRow();

            for (FieldMeta field : fieldMetas) {
                field.readFieldValue(row, resultSet);
            }
        }

    }

    public DataRow createRow() {
        int colCount = this.tableMeta.getSelectFieldMetas().size();
        DataRow row = new DataRow(colCount);

        if (this.rows == null) {
            this.rows = new ArrayList<>();
        }

        this.rows.add(row);

        return row;
    }

    public int getRowIndexByKeyValue(Object value) {
        if (rowIndexMap == null) {
            rowIndexMap = new HashMap<Object, Integer>(rows.size(), 1);
            int keyColIndex = tableMeta.getPkFieldMeta().getSelectIndex();

            for (int i = 0; i < rows.size(); i++) {
                rowIndexMap.put(rows.get(i).values[keyColIndex], i);
            }
        }

        Integer idx = rowIndexMap.get(value);

        if (idx == null) {
            throw new IllegalArgumentException("value:" + value + ", is not found");
        }

        return idx;
    }

    public List<DataRow> getRows() {
        if (rows == null) {
            return Collections.emptyList();
        }
        return rows;
    }

    public TableMeta getTableMeta() {
        return tableMeta;
    }
}
